﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Diagnostics;

namespace GMusicBoxUpdater
{
    public partial class frmDownloading : Form
    {
        public frmDownloading(UpdateItem[] data, string dstMainProgram)
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;

            this.data = data;
            dst = dstMainProgram;
            dwr.Connected += new EventHandler(dwr_Connected);
            dwr.ConnectFailed += new EventHandler(dwr_ConnectFailed);
            dwr.DownloadCompleted += new EventHandler(dwr_DownloadCompleted);

            List<string> nd = new List<string>();
            int downloadCount = 0;
            foreach (UpdateItem ui in data)
            {
                if (ui.Type != UpdateType.Delete)
                {
                    downloadCount++;
                    nd.Add(ui.Url);
                }
            }

            needDownload = nd.ToArray();
            progressBar1.Style = ProgressBarStyle.Continuous;
            progressBar1.Maximum = 100 * downloadCount;
        }

        Downloader dwr = new Downloader();
        int currentDownload = 0;
        UpdateItem[] data;
        string[] needDownload = new string[0];
        string dst = "";
        delegate void EventCallBack(object sender, EventArgs e);

        private void dwr_Connected(object sender, EventArgs e)
        {
            try
            {
                if (this.InvokeRequired)
                    this.Invoke(new EventCallBack(dwr_Connected), sender, e);
                else
                {
                    timer1.Enabled = true;
                    timer2.Enabled = true;
                    timer1_Tick(timer1, null);
                }
            }
            catch { }
        }

        private void dwr_DownloadCompleted(object sender, EventArgs e)
        {
            if (this.InvokeRequired)
                this.Invoke(new EventCallBack(dwr_DownloadCompleted), sender, e);
            else
            {
                timer1.Enabled = false;
                timer2.Enabled = false;
                currentDownload++;
                if (currentDownload >= needDownload.Length)
                {
                    try
                    {
                        label1.Text = "下载完成，正在更新文件...";
                        label2.Visible = false;
                        progressBar1.Style = ProgressBarStyle.Marquee;

                        bool createNew = false;
                        while (!createNew)
                        {
                            Mutex m = new Mutex(true, "hjkcaiAndMyCreat.GoogleMusicBox", out createNew);
                            if (!createNew)
                            {
                                DialogResult dr = MessageBox.Show("检测到当前谷歌音乐盒正在运行，请先关闭谷歌音乐盒后，点击“重试”按钮继续更新。\n如果多次重试后依然无法更新，您可以点击“忽略”按钮强行关闭谷歌音乐盒，但这可能会造成数据丢失。", "提示", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Exclamation);
                                if (dr == DialogResult.Retry)
                                {
                                    m.Close();
                                    continue;
                                }
                                else if (dr == DialogResult.Abort) break;
                                else
                                {
                                    string fn = Directory.GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\GMusicBox", "@*")[0];
                                    fn = Path.GetFileName(fn).Substring(1);
                                    try
                                    {
                                        Process p = Process.GetProcessById(int.Parse(fn));
                                        p.Kill();
                                    }
                                    catch { }
                                    createNew = true;
                                }
                            }
                            m.Close();
                        }

                        if (createNew)
                        {
                            string path = Path.GetDirectoryName(dst);
                            for (int i = 0; i < data.Length; i++)
                            {
                                int dels = 0;
                                string fileName = "";
                                if (data[i].IsMainProgram) fileName = dst;
                                else fileName = path + "\\" + data[i].Url.Substring(data[i].Url.LastIndexOf("/") + 1);

                                if (File.Exists(fileName))
                                {
                                    while (dels < 100)
                                    {
                                        try
                                        {
                                            File.Delete(fileName);
                                            break;
                                        }
                                        catch { }
                                        System.Threading.Thread.Sleep(100);
                                        dels++;
                                    }

                                    if (dels >= 100)
                                    {
                                        MessageBox.Show("尝试删除文件“" + fileName + "”时出错，请到谷歌音乐盒官方网站手动下载最新版本。", "更新失败", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                                        this.DialogResult = DialogResult.OK;
                                    }
                                }

                                if (data[i].Type != UpdateType.Delete)
                                {
                                    string tmpFile = Application.StartupPath + "\\" + data[i].Url.Substring(data[i].Url.LastIndexOf("/") + 1) + ".tmp";
                                    File.Move(tmpFile, fileName);
                                }
                            }

                            if (MessageBox.Show("更新成功！是否立即运行谷歌音乐盒？", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
                                Process.Start(dst);
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("更新失败，请到谷歌音乐盒官方网站手动下载最新版本。\n\n详细信息：\n" + ex.ToString(), "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    }

                    this.DialogResult = DialogResult.OK;
                }
                else StartDownload();
            }
        }

        private void dwr_ConnectFailed(object sender, EventArgs e)
        {
            MessageBox.Show("下载更新文件失败！请检查您的网络是否正常或换个时间段再试。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            this.DialogResult = DialogResult.OK;
        }

        private void StartDownload()
        {
            label1.Text = "正在连接...";
            label2.Text = "下载第 " + (currentDownload + 1).ToString() + " 个文件，共 " + needDownload.Length.ToString() + " 个";
            dwr.Url = needDownload[currentDownload];
            if (!dwr.Url.StartsWith("http://")) dwr.Url = "http://" + dwr.Url;
            dwr.FileName = Application.StartupPath + "\\" + dwr.Url.Substring(dwr.Url.LastIndexOf("/") + 1) + ".tmp";
            dwr.Start();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            label1.Text = Helper.GetStringFromBytes(dwr.DownloadedSize) + " / " + Helper.GetStringFromBytes(dwr.FileLenght);
            //int speed = dwr.DownloadedSize - oldDownloadedSize;
            //int remainTime = speed == 0 ? -1 : (dwr.FileLenght - dwr.DownloadedSize) / speed; 
            //if (remainTime != -1) label1.Text = "还剩约 " + remainTime.ToString() + " 秒";
            //oldDownloadedSize = dwr.DownloadedSize;
        }

        private void timer2_Tick(object sender, EventArgs e)
        {
            if (dwr.FileLenght == 0) progressBar1.Value = currentDownload * 100;
            else progressBar1.Value = (int)(currentDownload * 100 + (dwr.DownloadedSize / (double)dwr.FileLenght) * 100);
        }

        private void frmDownloading_Load(object sender, EventArgs e)
        {
            StartDownload();
        }

        private void frmDownloading_FormClosing(object sender, FormClosingEventArgs e)
        {
            dwr.Stop();
            timer1.Enabled = false;
            timer2.Enabled = false;
        }
    }
}
